package com.bfly.mall.order.api;

import com.alibaba.fastjson.JSONObject;
import com.bfly.common.ResponseUtil;
import com.bfly.common.json.JsonUtil;
import com.bfly.common.util.DataConvertUtils;
import com.bfly.core.base.controller.BaseController;
import com.bfly.core.base.entity.ResponseData;
import com.bfly.core.enums.AccessRole;
import com.bfly.core.enums.SysError;
import com.bfly.core.exception.ServiceResponseException;
import com.bfly.core.security.ActionModel;
import com.bfly.core.security.Login;
import com.bfly.mall.order.dto.*;
import com.bfly.mall.order.entity.Order;
import com.bfly.mall.order.entity.OrderAddress;
import com.bfly.mall.order.entity.OrderExpress;
import com.bfly.mall.order.entity.OrderSku;
import com.bfly.mall.order.enums.ExpressStatusEnum;
import com.bfly.mall.order.enums.OrderOpTypeEnum;
import com.bfly.mall.order.enums.OrderStatusEnum;
import com.bfly.mall.order.enums.PayStatusEnum;
import com.bfly.mall.order.service.IOrderService;
import com.bfly.mall.user.entity.User;
import com.bfly.mall.wechat.minipro.dto.WeChatOrderQueryResponse;
import com.bfly.mall.wechat.minipro.service.WeChatMiniProOrderApi;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单API Controller
 *
 * @author 长沙商脉科技有限公司
 * @date 2020/4/19 9:23
 */
@RestController
@RequestMapping(value = "/api/order")
public class OrderApiController extends BaseController {

    @Autowired
    private IOrderService orderService;

    /**
     * 下订单
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/4/25 14:18
     */
    @PostMapping(value = "/booking")
    @ActionModel(value = "提交新订单")
    @Login
    public void bookingOrder(@RequestBody BookingOrderDTO orderDTO, HttpServletResponse response) {
        String orderNo = orderService.bookingOrder(getUser(), orderDTO);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(orderNo));
    }

    /**
     * 订单列表
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/11/28 14:05
     */
    @GetMapping(value = "/list")
    @Login
    public void listOrder(HttpServletResponse response, HttpServletRequest request) {
        String status = request.getParameter("status");
        Map<String, Object> param = new HashMap<>();
        if (StringUtils.isNotBlank(status)) {
            int type = DataConvertUtils.convertToInteger(status);
            switch (type) {
                case 1:
                    // 待发货
                    param.put("order_status", OrderStatusEnum.OPEN.getId());
                    param.put("pay_status", PayStatusEnum.SUCCESS.getId());
                    param.put("express_status", ExpressStatusEnum.WAIT_SHIP.getId());
                    break;
                case 3:
                    // 待收货
                    param.put("order_status", OrderStatusEnum.OPEN.getId());
                    param.put("pay_status", PayStatusEnum.SUCCESS.getId());
                    param.put("express_status", ExpressStatusEnum.SHIPPING.getId());
                    break;
                case 4:
                    // 待付款
                    param.put("order_status", OrderStatusEnum.OPEN.getId());
                    param.put("pay_status", PayStatusEnum.WAIT_PAY.getId());
                    param.put("express_status", ExpressStatusEnum.INITIAL.getId());
                    break;
                case 6:
                    // 已完成
                    param.put("order_status", OrderStatusEnum.COMPLETE.getId());
                    param.put("pay_status", PayStatusEnum.SUCCESS.getId());
                    param.put("express_status", ExpressStatusEnum.RECEIVED.getId());
                    break;
            }
        }
        param.put("user_id", getUser().getId());
        param.put("is_deleted", false);

        List<Order> orders = orderService.getList(param);
        List<OrderListDTO> list = new ArrayList<>();
        if (orders != null) {
            OrderAddress address;
            for (Order order : orders) {
                address = order.getAddress();
                List<OrderSku> skus = order.getSkus();
                OrderListDTO dto = new OrderListDTO();

                dto.setOrderNo(order.getOrderNo());
                dto.setOrderStatus(order.getOrderStatus());
                dto.setPayStatus(order.getPayStatus());
                dto.setExpressStatus(order.getExpressStatus());
                dto.setDispatchId(order.getDispatchId());
                dto.setCreateDate(order.getCreateDate());
                dto.setPayPrice(order.getPayPrice());

                if (address != null) {
                    dto.setConsignee(address.getConsignee());
                    dto.setPhone(address.getPhone());
                    dto.setAddress(String.format("%s - %s %s %s %s", address.getPostCode(), address.getProvince(), address.getCity(), address.getDistrict(), address.getAddress()));
                }
                List<OrderSkuListDTO> skuListDTOS = new ArrayList<>();
                skus.forEach(sku -> {
                    OrderSkuListDTO skuListDTO = new OrderSkuListDTO();
                    BeanUtils.copyProperties(sku, skuListDTO);
                    skuListDTOS.add(skuListDTO);
                });

                dto.setSkus(skuListDTOS);
                list.add(dto);
            }
        }
        ResponseUtil.writeJson(response, ResponseData.getSuccess(list));
    }

    /**
     * 订单详情
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/4/19 9:51
     */
    @GetMapping(value = "/detail")
    @Login
    public void detailOrder(@RequestParam(value = "orderNo", defaultValue = "") String orderNo, HttpServletResponse response) {
        Order order = orderService.getOrder(orderNo, getUser().getId());
        if (order == null) {
            throw new ServiceResponseException(SysError.PARAM_ERROR, "订单信息不存在!");
        }
        OrderDTO dto = new OrderDTO();
        dto.setOrderNo(orderNo);
        dto.setTradeNo(order.getTradeNo());
        dto.setProductPrice(order.getProductPrice());
        dto.setPayPrice(order.getPayPrice());
        dto.setDiscountPrice(order.getDiscountPrice());
        dto.setExpressPrice(order.getExpressPrice());
        dto.setOrderStatus(order.getOrderStatus());
        dto.setPayStatus(order.getPayStatus());
        dto.setExpressStatus(order.getExpressStatus());
        dto.setPayType(order.getPayType());
        dto.setDispatchId(order.getDispatchId());
        dto.setActivityType(order.getActivityType());
        dto.setRemark(order.getRemark());

        List<OrderSku> skus = order.getSkus();
        List<OrderSkuListDTO> skuListDTOS = new ArrayList<>();
        skus.forEach(sku -> {
            OrderSkuListDTO skuListDTO = new OrderSkuListDTO();
            BeanUtils.copyProperties(sku, skuListDTO);
            skuListDTOS.add(skuListDTO);
        });
        dto.setSkus(skuListDTOS);

        dto.setLogs(order.getLogs());

        OrderAddress address = order.getAddress();
        if (address != null) {
            OrderAddressDTO addressDTO = new OrderAddressDTO();
            addressDTO.setPhone(address.getPhone());
            addressDTO.setConsignee(address.getConsignee());
            addressDTO.setAddress(String.format("%s %s %s %s", address.getProvince(), address.getCity(), address.getDistrict(), address.getAddress()));
            dto.setAddress(addressDTO);
        }

        List<OrderExpress> expresses = order.getExpress();
        List<OrderExpressDTO> expressDTOS = new ArrayList<>();
        expresses.forEach(express -> {
            OrderExpressDTO expressDTO = new OrderExpressDTO();
            BeanUtils.copyProperties(express, expressDTO);
            expressDTOS.add(expressDTO);
        });
        dto.setExpress(expressDTOS);

        JSONObject json = JsonUtil.toJsonFilter(dto);
        json.put("canPay", order.isCanPay());
        json.put("canCancel", order.isCanCancel());
        json.put("canConfirmReceive", order.isCanConfirmReceive());
        if (CollectionUtils.isNotEmpty(order.getLogs())) {
            order.getLogs().forEach(logs -> {
                if (logs.getType() == OrderOpTypeEnum.BOOKING_MEMBER.getId()) {
                    //下单时间
                    json.put("createDate", logs.getCreateDate());
                }
                if (logs.getType() == OrderOpTypeEnum.PAY_MEMBER.getId()) {
                    // 支付时间
                    json.put("payDate", logs.getCreateDate());
                }
            });
        }
        ResponseUtil.writeJson(response, ResponseData.getSuccess(json));
    }


    /**
     * 取消订单
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/11/30 17:28
     */
    @GetMapping(value = "/cancel")
    @ActionModel(value = "取消订单")
    @Login
    public void cancelOrder(@RequestParam("orderNo") String orderNo, HttpServletResponse response) {
        User user = getUser();
        orderService.cancelOrder(orderNo, "用户主动取消订单", user.getId(), user.getNickName(), AccessRole.USER);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(""));
    }


    /**
     * 发起微信小程序支付
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/11/30 17:31
     */
    @GetMapping(value = "/minipro/pay")
    @ActionModel(value = "发起订单支付")
    @Login
    public void payOrder(HttpServletResponse response, @RequestParam("orderNo") String orderNo) {
        JSONObject json = orderService.toPayOrder(getUser(), orderNo);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(json));
    }

    /**
     * 查询微信服务器订单的交易状态
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/12/4 12:12
     */
    @GetMapping(value = "/query/trade/status")
    @Login
    public void queryOrderPayStatus(HttpServletResponse response, @RequestParam("orderNo") String orderNo) {
        Order order = orderService.getOrder(orderNo, getUser().getId());
        if (order == null) {
            throw new ServiceResponseException(SysError.PARAM_ERROR, "不存在的订单信息!");
        }
        WeChatOrderQueryResponse result = WeChatMiniProOrderApi.queryOrderTradeStatusFromWeChat(orderNo);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(result.getTrade_state()));
    }

    /**
     * 买家确认收货操作
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/4/25 19:59
     */
    @GetMapping(value = "/confirm/receive")
    @ActionModel(value = "商家确认收货")
    @Login
    public void confirmReceiveShopKeeper(@RequestParam("orderNo") String orderNo, HttpServletResponse response) {
        orderService.confirmReceiveOrder(orderNo, "买家确认收货", getUser().getId(), getUser().getNickName(), AccessRole.USER);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(""));
    }
}
